package org.lmib.abt.checkers;
/*
 * Copyright (c) 1996/1997 F. Di Fabio
 * All rights reserved.
 * 
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc., 675
 * Mass Ave, Cambridge, MA 02139, USA.
 */


import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Vector;

class CanvasCheckersBoard extends Canvas {
  static final int NUMBERHEIGHT = 11;
  static final int SIDELENGTH = 35;
  
  private static final Dimension PREFERRED_SIZE = new Dimension(310,310);
  Image images[];
  PieceOfBoard boxCoord[] = new PieceOfBoard[32];
  
  private Image offImage;
  private Graphics offGraphics;

  int userSelection;
  boolean editMode;
  int pieceType;
  Vector selectedBox = new Vector();
  int paintState[] = new int[32];
  Vector paintComputerMove = new Vector();
  boolean animation = false;
  
  private Point endPoint = new Point(0,0);
  

public void handleMouseMove(Point point) {

    if(selectedBox.isEmpty() == false) {
		endPoint.x = point.x;
		endPoint.y = point.y;
		repaint();
    }
}

public Dimension preferredSize() {

    return PREFERRED_SIZE;
}

public CanvasCheckersBoard() {

    editMode = false;

    int i = 0;
    int j = 0;
    for(i=0;i<4;i++) {
		for(j=0;j<4;j++) {
		    boxCoord[i*8+j] = new PieceOfBoard(j*2*SIDELENGTH,i*2*SIDELENGTH);
		    boxCoord[(i*8+4)+j] = new PieceOfBoard((j*2+1)*SIDELENGTH,(i*2+1)*SIDELENGTH);
		}
    }

    for(i=0;i<32;i++){
    	boxCoord[i].translate(5,5+NUMBERHEIGHT);
    }
    
    
    
    addMouseMotionListener(new MouseAdapter() {

		public void mouseMoved(MouseEvent e) {
			handleMouseMove(e.getPoint());
			super.mouseMoved(e);
		}
    });
    
    addMouseListener(new MouseAdapter(){
    	
		public void mouseClicked(MouseEvent e) {
			handleMouseDown(e.getPoint());
			super.mouseClicked(e);
		}    	
    });
}

private void handleMouseDown(Point point) {
  int mouseRow;
  int mouseCol;
  
    mouseRow = (point.y - 5) / 35;
    mouseCol = (point.x - 5) / 35;

    userSelection = CheckersGlobal.UNDEF;
    
    if((mouseRow%2 == 0) && (mouseCol%2 == 0)) {  
    	userSelection = mouseRow*4+mouseCol/2;
    }
	
    if((mouseRow%2 == 1) && (mouseCol%2 == 1)) {
    	userSelection = mouseRow*4+mouseCol/2;
    }

    if(animation == true && userSelection != CheckersGlobal.UNDEF) {
		selectedBox.addElement( new Point(boxCoord[userSelection].x + 17, boxCoord[userSelection].y + 10));
		endPoint.x = point.x;
		endPoint.y = point.y;
    }
    
    paintComputerMove.removeAllElements();    
}

public void update(Graphics g) {

  paint(g);
}

public void paint(Graphics g) {
  int i;
  Point p1,p2;

    if(offGraphics == null) {
		offImage = createImage(291,291);
		offGraphics = offImage.getGraphics();
		offGraphics.drawRect(0,0,290,290);
		offGraphics.drawRect(4,4,281,281);
    }

    offGraphics.fillRect(0,0,291,291);
    offGraphics.drawImage(images[CheckersGlobal.TOTALBOARD],5,5,this);

    for(i=0;i<32;i++) {
    	offGraphics.drawImage(images[paintState[i]], boxCoord[i].x, boxCoord[i].y, this);
    }
	
    if(paintComputerMove.isEmpty() == false) {
		p1 = boxCoord[((Integer)paintComputerMove.elementAt(0)).intValue()];
		for(i=1; i<paintComputerMove.size(); i++) {
		    p2 = boxCoord[((Integer)paintComputerMove.elementAt(i)).intValue()];
		    drawArrow(offGraphics, p1.x + 17, p1.y + 10, p2.x + 17, p2.y + 10);
		    p1 = p2;	    
		}
	
    }
	
    if(animation == true) {

		if(selectedBox.isEmpty() == false) {
		    p1 = (Point)selectedBox.elementAt(0);
		    for(i=1; i<selectedBox.size(); i++) {
				p2 = (Point)selectedBox.elementAt(i);
				drawArrow(offGraphics, p1.x, p1.y, p2.x, p2.y);
				p1 = p2;
		    }
		    drawArrow(offGraphics, p1.x, p1.y, endPoint.x, endPoint.y);
		}
    }
    g.drawImage(offImage,0,0,this);
    
}

public void drawArrow(Graphics g, int x1, int y1, int x2, int y2) {
  Polygon arrowIn = new Polygon();
  double xDiff;
  double yDiff;
  double alfa;
  int xOffset1;
  int yOffset1;
  int xOffset2;
  int yOffset2;
  
    xDiff = Math.abs(x1 - x2);
    yDiff = Math.abs(y1 - y2);
    if(xDiff == 0) {
    	alfa = Math.PI / 2;
    }
    else {
    	alfa = Math.atan(yDiff / xDiff);
    }
    
    xOffset1 = (int)(10 * Math.sin(alfa));
    yOffset1 = (int)(10 * Math.cos(alfa));
    xOffset2 = (int)(15 * Math.sin(alfa));
    yOffset2 = (int)(15 * Math.cos(alfa));
    

    if(y1 < y2) {
		if(x1 < x2) {
		    arrowIn.addPoint(x1 - xOffset1, y1 + yOffset1);
		    arrowIn.addPoint(x1 + xOffset1, y1 - yOffset1);
		    arrowIn.addPoint(x2 - yOffset2 + xOffset1, y2 - xOffset2 - yOffset1);
		    arrowIn.addPoint(x2 - yOffset2 + xOffset2, y2 - xOffset2 - yOffset2);
		    arrowIn.addPoint(x2, y2 );
		    arrowIn.addPoint(x2 - yOffset2 - xOffset2, y2 - xOffset2 + yOffset2);
		    arrowIn.addPoint(x2 - yOffset2 - xOffset1, y2 - xOffset2 + yOffset1);
		    arrowIn.addPoint(x1 - xOffset1, y1 + yOffset1);
		}
		else {
		    arrowIn.addPoint(x1 - xOffset1, y1 - yOffset1);
		    arrowIn.addPoint(x1 + xOffset1, y1 + yOffset1);
		    arrowIn.addPoint(x2 + yOffset2 + xOffset1, y2 - xOffset2 + yOffset1);
		    arrowIn.addPoint(x2 + yOffset2 + xOffset2, y2 - xOffset2 + yOffset2);
		    arrowIn.addPoint(x2, y2 );
		    arrowIn.addPoint(x2 + yOffset2 - xOffset2, y2 - xOffset2 - yOffset2);
		    arrowIn.addPoint(x2 + yOffset2 - xOffset1, y2 - xOffset2 - yOffset1);
		    arrowIn.addPoint(x1 - xOffset1, y1 - yOffset1);
		}
    }
    else {
		if(x1 < x2) {
		    arrowIn.addPoint(x1 + xOffset1, y1 + yOffset1);
		    arrowIn.addPoint(x1 - xOffset1, y1 - yOffset1);
		    arrowIn.addPoint(x2 - yOffset2 - xOffset1, y2 + xOffset2 - yOffset1);
		    arrowIn.addPoint(x2 - yOffset2 - xOffset2, y2 + xOffset2 - yOffset2);
		    arrowIn.addPoint(x2, y2 );
		    arrowIn.addPoint(x2 - yOffset2 + xOffset2, y2 + xOffset2 + yOffset2);
		    arrowIn.addPoint(x2 - yOffset2 + xOffset1, y2 + xOffset2 + yOffset1);
		    arrowIn.addPoint(x1 + xOffset1, y1 + yOffset1);
		}
		else {
		    arrowIn.addPoint(x1 + xOffset1, y1 - yOffset1);
		    arrowIn.addPoint(x1 - xOffset1, y1 + yOffset1);
		    arrowIn.addPoint(x2 + yOffset2 - xOffset1, y2 + xOffset2 + yOffset1);
		    arrowIn.addPoint(x2 + yOffset2 - xOffset2, y2 + xOffset2 + yOffset2);
		    arrowIn.addPoint(x2, y2 );
		    arrowIn.addPoint(x2 + yOffset2 + xOffset2, y2 + xOffset2 - yOffset2);
		    arrowIn.addPoint(x2 + yOffset2 + xOffset1, y2 + xOffset2 - yOffset1);
		    arrowIn.addPoint(x1 + xOffset1, y1 - yOffset1);
		}    
    }
        
    g.setColor(Color.yellow);
    g.fillPolygon(arrowIn);
    g.setColor(Color.black);
    g.drawPolygon(arrowIn);
}
}
